﻿function Set-NetConnectionId {
<#
.SYNOPSIS
Modifies NetConnectionId using Windows Management Instrumentation (WMI)
.DESCRIPTION
Modifies NetConnectionId using Windows Management Instrumentation (WMI) on Network Interface Cards configured with a static IP address.
.PARAMETER ComputerName
The computer to perform action against. Defaults to the local computer if not specified. Accepts ValueFromPipeline and ValueFromPipelineByPropertyName.
.PARAMETER NetConnectionId
Only NICs matching the specified NetConnectionId will be modified
.PARAMETER DefaultGatewayPresentOnly
Switch-parameter to modify NIC with a default gateway present only
.PARAMETER DNSServerSearchOrder
The new value for the DNS Server Search Order. The first entry will be set as primary DNS server, the second entry as the secondary DNS server etc.
.PARAMETER Logfile
Path to log-file (only errors is logged)
.EXAMPLE
Set-NetConnectionId -NewNetConnectionId "VLAN 400" -Subnet 172.16.34.0
.EXAMPLE
Set-NetConnectionId -ComputerName (Get-Content c:\computernames.txt)  -NewNetConnectionId "VLAN 400" -Subnet 172.16.34.0
.EXAMPLE
Import-Module ActiveDirectory;Get-ADComputer -filter * | Select-Object @{l='computername';e={$_.Name}} | Set-NetConnectionId -NewNetConnectionId "VLAN 400" -Subnet 172.16.34.0
.EXAMPLE
Set-NetConnectionId -NewNetConnectionId "VLAN 400" -Subnet 172.16.34.0 -DefaultGatewayPresentOnly
.EXAMPLE
Set-NetConnectionId -NewNetConnectionId "VLAN 400" -Subnet 172.16.34.0 -NetConnectionId "Local Area Connection"
.NOTES
AUTHOR:    Jan Egil Ring
BLOG:      http://blog.powershell.no
LASTEDIT:  15.10.2011
#Requires -Version 2.0
#>

    [CmdletBinding()]
    param(
        [Parameter(ValueFromPipeline=$True,ValueFromPipelineByPropertyName=$True)]
        [string[]]$ComputerName = "localhost",
        [Parameter(Mandatory=$True)]
        [string]$NewNetConnectionId,
        [switch]$DefaultGatewayPresentOnly,
        [Parameter(Mandatory=$True)]
        [ValidateScript({[ipaddress] $_ -and $_ -match "\b([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\b"})]
        [string]$Subnet,
        [string]$Logfile
    )
    BEGIN {
    
       if ($logfile) {
        New-Item -Path $Logfile -ItemType file -Force | Out-Null
        }                   

    }
    PROCESS {
        if ($PSBoundParameters.ContainsKey('computername')) {
            foreach ($computer in $computername) {
                Write-Verbose 'Input from parameter'
                Set-NetConnectionIdWorker -computername $computername
            }
        } else {
            Write-Verbose 'Input from pipeline'
            Set-NetConnectionIdWorker -computername $computername
        }
    }
}

#Helper function
function Set-NetConnectionIdWorker {
    param($computername)
    $continue = $True
    try {
        if ((Test-Connection -ComputerName $computername -Count 1 -Quiet) -and ($computersystem = Get-WmiObject -Class win32_computersystem -Computername $computername -ErrorAction stop)) {
        Write-Verbose "Connected to computer $computername"
        $NICs = Get-WmiObject -Query "SELECT * FROM Win32_NetworkAdapterConfiguration WHERE IPEnabled = TRUE" -ComputerName $computername -ErrorAction Stop
        
        if ($DefaultGatewayPresentOnly) {
        Write-Verbose 'Filtering NICs with default gateway present'
        $NICs = $NICs | Where-Object {$_.DefaultIPGateway}
        }
        
        if ($NetConnectionId) {
        Write-Verbose "Searching for NIC with NetConnectionId $NetConnectionId"
        $NetConnectionIdMatch = Get-WmiObject -Query "SELECT * FROM Win32_NetworkAdapter WHERE NetConnectionId = `'$NetConnectionId`'" -ComputerName $computername
        $NICs = $NICs | Where-Object {$_.Index -eq $NetConnectionIdMatch.index}
        if ($NICs) {
        Write-Verbose "Found NIC with NetConnectionId $NetConnectionId"
                   }
        }
        
        if ($NICs) {
        
        $nicinfo = @{}
        $NetConnectionId = @()
        $ModifiedNetConnectionId = @()
        $modified = @()
        $Description = @()
        
        $subnet = (([ipaddress] $subnet).GetAddressBytes()[0..2] -join ".") + "."

        foreach ($NIC in $NICs) {
        
        Write-Verbose "Processing NIC $($NIC.Description)"
        
        $SubnetCompare = $nic.IPAddress -join ","

        if ($SubnetCompare -match $Subnet) {

        Write-Verbose "Found NIC with specified subnet, executing put WMI-method"

        $NetworkAdapter = Get-WmiObject -Query "SELECT * FROM Win32_NetworkAdapter WHERE Index = $($NIC.Index)" -ComputerName $computername
        $NetConnectionId  += $NetworkAdapter.NetConnectionId
        $Description += $NIC.Description

        Write-Verbose "Executing put WMI-method"

        $NewNetConnectionIdValue = $NewNetConnectionId

        if (-not ($NetworkAdapter.NetConnectionId -eq $NewNetConnectionIdValue)) {

        $counter = 1
        while (Get-WmiObject -Query "SELECT * FROM Win32_NetworkAdapter WHERE NetConnectionId = `'$NewNetConnectionIdValue`'" -ComputerName $computername)
        {
        $counter ++
        $NewNetConnectionIdValue = $NewNetConnectionId + ' #' + $counter
        }

        $NetworkAdapter.NetConnectionId=$NewNetConnectionIdValue
        $result = $NetworkAdapter.psbase.put()
        }
        else {
        Write-Verbose "$NewNetConnectionId already set on adapter $($NIC.Description), adapter was not modified"
        }

        if ($result) {
        $modified += "1"
        $ModifiedNetConnectionId += $NetworkAdapter.NetConnectionId
        }
        else {
        $modified += "0"
        }
        }
        else {
        Write-Verbose "NIC with specified subnet not found"
        }

        
    }
        
        }
        
        $nicinfo.NetConnectionId = $NetConnectionId
        $nicinfo.NewNetConnectionId = $ModifiedNetConnectionId
        $nicinfo.Modified = $modified
        $nicinfo.Description = $Description
        
        

}
        
    } 
    
    catch {
        Write-Verbose "An error occured connecting to computer $computername"
        Write-Verbose $error[0].exception

        if ($logfile) {
        $computername | Out-File -FilePath $Logfile -Append
        $error[0].exception | Out-File -FilePath $Logfile -Append
        }
    }
        
        Write-Verbose "Writing output object"
                
        $computerinfo = @{}
        $computerinfo.ComputerName = $computersystem.name
        $computerinfo.NICCount = ($NICs | Measure-Object).count
        $computerinfo.NetConnectionID = ($nicinfo | Select-Object @{Name='NetConnectionId';Expression={[string]::join(";", ($_.NetConnectionId))}}).NetConnectionId
        $computerinfo.NICDescription = ($nicinfo | Select-Object @{Name='Description';Expression={[string]::join(";", ($_.Description))}}).Description
        $computerinfo.NewNetConnectionId = ($nicinfo | Select-Object @{Name='NewNetConnectionId';Expression={[string]::join(";", ($_.NewNetConnectionId))}}).NewNetConnectionId
                                
        $obj = New-Object -TypeName PSObject -Property $computerinfo

        Write-Output $obj | Select-Object ComputerName,NICCount,NetConnectionID,NewNetConnectionId,NICDescription
}